package com.gitee.wsl.lang.bits

import com.gitee.wsl.lang.bits.api.Accountable
import com.gitee.wsl.lang.bits.api.Bits

/*
 * All changes to the original code are Copyright DataStax, Inc.
 *
 * Please see the included license file for details.
 */

/*
 * Original license:
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Base implementation for a bit set.
 */
abstract class AbstractBitSet : Bits, Accountable {
    /**
     * Clear all the bits of the set.
     *
     *
     * Depending on the implementation, this may be significantly faster than clear(0, length).
     */
    open fun clear() {
        // default implementation for compatibility
        clear(0, length())
    }

    /** Set the bit at `i`.  */
    abstract fun set(i: Int)

    operator fun set(bitIndex: Int, value: Boolean) {
        if (value)
            set(bitIndex)
        else
            clear(bitIndex)
    }

    /*fun set(fromIndex: Int, toIndex: Int, value: Boolean) {
        if (value)
            set(fromIndex, toIndex)
        else
            clear(fromIndex, toIndex)
    }*/

    /** Set the bit at `i`, returning `true` if it was previously set.  */
    abstract fun getAndSet(i: Int): Boolean

    /** Clear the bit at `i`.  */
    abstract fun clear(i: Int)

    /**
     * Clears a range of bits.
     *
     * @param startIndex lower index
     * @param endIndex one-past the last bit to clear
     */
    abstract fun clear(startIndex: Int, endIndex: Int)

    /** Return the number of bits that are set. NOTE: this method is likely to run in linear time  */
    abstract fun cardinality(): Int

    /**
     * Return an approximation of the cardinality of this set. Some implementations may trade accuracy
     * for speed if they have the ability to estimate the cardinality of the set without iterating
     * over all the data. The default implementation returns [.cardinality].
     */
    abstract fun approximateCardinality(): Int

    /**
     * Returns the index of the last set bit before or on the index specified. -1 is returned if there
     * are no more set bits.
     */
    abstract fun prevSetBit(index: Int): Int

    /**
     * Returns the index of the first set bit starting at the index specified. [ ][NO_MORE_DOCS] is returned if there are no more set bits.
     */
    abstract fun nextSetBit(index: Int): Int

    abstract fun clone(): AbstractBitSet

    override fun toString(): String {
        return this::class.simpleName + "(length=" + length() + ", cardinality=~" + approximateCardinality() + ")"
    }
    companion object{
        const val NO_MORE_DOCS = Int.MAX_VALUE
        private const val ADDRESS_BITS_PER_WORD = 6
        const val BITS_PER_WORD = 1 shl ADDRESS_BITS_PER_WORD
    }
}

